package rbac.interceptor;

import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.StrutsStatics;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import rbac.entity.RbacRole;
import rbac.entity.RbacUser;
import rbac.entity.RbacUserGroup;
import rbac.service.UserService;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.pandawork.core.exception.SSException;

/**
 * 访问权限控制拦截器.
 * 
 * @author Lionel
 */
public abstract class RBACInfoAbstractInitInterceptor extends
		AbstractInterceptor {

	private static final long serialVersionUID = 5154643114463542734L;

	/** 用户 service, 负责读取当前用户信息. */
	@Autowired
	@Qualifier("userService")
	protected UserService rbacUserService; // 用户 service.

	// ---=== Methods ===--- //

	@Override
	public void init() {
	}

	/**
	 * 拦截器验证方法.
	 * 
	 * @return 验证通过返回 invoke(), 不通过返回 "403", 用户未登录返回 <code>toLoginString</code>
	 *         中保存的字符串.
	 */
	@Override
	public String intercept(ActionInvocation inv) throws Exception {
		ActionContext ac = inv.getInvocationContext();
		HttpServletRequest request = (HttpServletRequest) ac
				.get(StrutsStatics.HTTP_REQUEST);

		// 获取登录名称
		String loginName = (String) request.getAttribute("loginName");

		RbacUser rbacUser = rbacUserService.getUser(loginName); // 获取RBAC中的用户
		RbacRole role = queryRole(rbacUser); // 获取角色
		excute(inv, loginName, rbacUser, role);

		return inv.invoke();
	}

	private RbacRole queryRole(RbacUser rbacUser) {
		Set<RbacUserGroup> userGroups = rbacUser.getUserGroups();
		RbacRole role = null;

		for (RbacUserGroup ug : userGroups) {
			for (RbacRole r : ug.getRoles()) {
				if (r != null) {
					role = r;
					return role;
				}
			}
		}

		return role;
	}

	public abstract void excute(ActionInvocation inv, String loginName,
			RbacUser rbacUser, RbacRole role) throws SSException;
}
